﻿using System.Collections.Generic;
using System.Linq;

namespace Tuxedo.Compile
{
	internal class ConstructorCall : Expression
	{
		public UnverifiedType Type { get; private set; }
		public Expression[] Parameters { get; private set; }
		public Expression[] Keys { get; private set; }
		public Expression[] Values { get; private set; }
		public ConstructorInitializerStyle InitializerStyle { get; private set; }

		public ConstructorCall(UnverifiedType type, IList<Expression> parameters, IList<Expression> keys, IList<Expression> values)
		{
			this.Type = type;
			this.Parameters = parameters.ToArray();
			this.InitializerStyle = ConstructorInitializerStyle.None;

			if (keys == null)
			{
				this.Keys = null;
				this.Values = null;
			}
			else
			{
				this.Keys = keys.ToArray();
				this.Values = values.ToArray();

				if (this.Keys.Length > 0)
				{
					this.InitializerStyle = this.DetermineStyle(this.Keys, this.Values, 0);
					for (int i = 1; i < this.Keys.Length; ++i)
					{
						if (this.InitializerStyle != this.DetermineStyle(this.Keys, this.Values, i))
						{
							throw new System.Exception("Cannot mix and match dictionary/list/property initializers for a constructor");
						}
					}
				}
			}
		}

		private ConstructorInitializerStyle DetermineStyle(Expression[] keys, Expression[] values, int index)
		{
			if (keys[index] != null)
				return ConstructorInitializerStyle.Dictionary;

			if (values[index] is AssignmentExpression)
				return ConstructorInitializerStyle.Properties;

			return ConstructorInitializerStyle.List;
		}
	}

	internal enum ConstructorInitializerStyle
	{
		None,
		Properties,
		List,
		Dictionary
	}
}
